#include "mem_slabs.h"

class Slab {
    uint16_t chunks_size;
    Chunk* _used_head;
    Chunk* _free_head;
    uint16_t _size;
    char _data[0];
public:
    static Slab* open(char* ptr, int size) {
        Slab* slab = (Slab*)ptr;
        if (sizeof(Slab) > size) {
            return NULL;
        }
        slab->_freeChunksHead = NULL;
        slab->_usedChunskHead = NULL;
        slab->_size = size;
        return slab;
    }
};

class SlabClass {
    unsigned int _size;      /* sizes of items */
    unsigned int _perslab;   /* how many items per slab */

    Slab** _slabs;
    int _slabs_size;

    Chunk* _free_chunk_head;
    //stat
    size_t _requested;
public:
    static SlabClass* open(char* ptr, int size) {
        SlabClass* slabClass = (SlabClass*)ptr;
        slabClass->_size = 0;
        slabClass->_perslab = 0;
        slabclass->_killing = 0;
        slabclass->_requested = 0;
    }

    int init(MemAllocator* allocator) {

    }

private:
    int grow_slabs() {
        size_t cur_size = slabs.size();
        if (cur_size == 0 || slabs[cur_size - 1] != 0) {
            size_t new_size = cur_size == 0 ? 16, 2 *  cur_size;
            slabs.resize(new_size);
        }
        return 0;
    }
};






int MemAllocator::init(const size_t limit, int slablimit = 18, int max_item_size = 1024 * 1024, const double factor = 1.2) {

    membase = malloc(limit);
    if (!membase) {
        return -1;
    }
    mem_limit = limit;
    mem_avail = mem_limit;
    mem_current = membase;

    slabClass.resize(slablimit);

    size_t size = 0;
    int i = 0;
    for (i = 0; i < slabClass.size() && size <= max_item_size / factor; i++) {
        slabClass[i].size = size;
        slabclass[i].perslab = max_item_size / slabclass[i].size;
        size *= factor;
        if (slabclass[i].init() != 0) {
            return -1;
        }
    }

    slabclass[i].size = max_item_size;
    slabclass[i].perslab = 1;

    return 0;
}

MemPage* MemAllocator::allocate(const size_t size)  {
    
}

void MemAllocator::deallocate(MemPage* page) {

}

//===========================================

char*  MemAllocator::do_allocate(int size) {
    
}

char*  MemAllocator::do_deallocate(int size) {
    
}

uint8_t MemAllocator::slabs_clsid(const size_t size) {
    if (size == 0) {
        return -1;
    }
    for (uint8_t i = 0; i < slabClass.size(); i++) {
        if (slabClass[i].size > size) {
            
        }
    }
}

